package api

import (
	"net/http"
	"os"
	"strconv"

	"github.com/gin-gonic/gin"
	"gorm.io/gorm"

	"crongo/internal/model"
	"crongo/internal/service"
)

type TaskHandler struct {
	db      *gorm.DB
	service *service.TaskService
}

func NewTaskHandler(db *gorm.DB, service *service.TaskService) *TaskHandler {
	return &TaskHandler{
		db:      db,
		service: service,
	}
}

// RegisterRoutes 注册路由
func (h *TaskHandler) RegisterRoutes(r *gin.Engine) {
	api := r.Group("/api")
	{
		api.GET("/tasks", h.ListTasks)
		api.POST("/tasks", h.CreateTask)
		api.PUT("/tasks/:id", h.UpdateTask)
		api.GET("/task-groups", h.GetTaskGroups)
		api.GET("/tasks/:id/logs", h.GetTaskLogs)
		api.GET("/tasks/:id/output", h.GetTaskLogFile)
		api.GET("/logs", h.GetRecentLogs)
		api.GET("/tasks/:id", h.GetTask)
		api.DELETE("/tasks/:id", h.DeleteTask)
	}
}

// ListTasks 获取任务列表
func (h *TaskHandler) ListTasks(c *gin.Context) {
	var tasks []model.Task
	var total int64

	// 分页参数
	page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
	pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "10"))
	if page < 1 {
		page = 1
	}
	if pageSize < 1 {
		pageSize = 10
	}

	// 查询条件
	query := h.db.Model(&model.Task{})
	if groupName := c.Query("group"); groupName != "" {
		query = query.Where("group_name = ?", groupName)
	}
	if status := c.Query("status"); status != "" {
		query = query.Where("status = ?", status)
	}

	// 计算总数
	query.Count(&total)

	// 获取分页数据
	offset := (page - 1) * pageSize
	if err := query.Offset(offset).Limit(pageSize).Find(&tasks).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"code":    500,
			"message": "获取任务列表失败",
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"code":    0,
		"message": "success",
		"data": gin.H{
			"total": total,
			"items": tasks,
		},
	})
}

// CreateTask 创建任务
func (h *TaskHandler) CreateTask(c *gin.Context) {
	var task model.Task
	if err := c.ShouldBindJSON(&task); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    400,
			"message": "无效的请求参数",
		})
		return
	}

	if err := h.service.CreateTask(&task); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"code":    500,
			"message": err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"code":    0,
		"message": "success",
		"data":    task,
	})
}

// UpdateTask 更新任务
func (h *TaskHandler) UpdateTask(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 64)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    400,
			"message": "无效的任务ID",
		})
		return
	}

	var task model.Task
	if err := c.ShouldBindJSON(&task); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    400,
			"message": "无效的请求参数",
		})
		return
	}

	task.ID = uint(id)
	if err := h.service.UpdateTask(&task); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"code":    500,
			"message": err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"code":    0,
		"message": "success",
		"data":    task,
	})
}

// DeleteTask 删除任务
func (h *TaskHandler) DeleteTask(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 64)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    400,
			"message": "无效的任务ID",
		})
		return
	}

	if err := h.service.DeleteTask(uint(id)); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"code":    500,
			"message": err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"code":    0,
		"message": "success",
	})
}

// GetTaskGroups 获取任务分组列表
func (h *TaskHandler) GetTaskGroups(c *gin.Context) {
	groups, err := h.service.GetTaskGroups()
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"code":    500,
			"message": "获取分组列表失败",
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"code":    0,
		"message": "success",
		"data":    groups,
	})
}

// GetTask 获取单个任务详情
func (h *TaskHandler) GetTask(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 64)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    400,
			"message": "无效的任务ID",
		})
		return
	}

	var task model.Task
	if err := h.db.First(&task, id).Error; err != nil {
		c.JSON(http.StatusNotFound, gin.H{
			"code":    404,
			"message": "任务不存在",
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"code":    0,
		"message": "success",
		"data":    task,
	})
}

// GetTaskLogs 获取任务执行记录
func (h *TaskHandler) GetTaskLogs(c *gin.Context) {
	taskID, err := strconv.ParseUint(c.Param("id"), 10, 64)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    400,
			"message": "无效的任务ID",
		})
		return
	}

	var logs []model.TaskLog
	if err := h.db.Where("task_id = ?", taskID).Order("id desc").Limit(100).Find(&logs).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"code":    500,
			"message": "获取执行记录失败",
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"code":    0,
		"message": "success",
		"data":    logs,
	})
}

// GetRecentLogs 获取最近的执行记录
func (h *TaskHandler) GetRecentLogs(c *gin.Context) {
	var logs []model.TaskLog
	if err := h.db.Order("id desc").Limit(100).Find(&logs).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"code":    500,
			"message": "获取执行记录失败",
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"code":    0,
		"message": "success",
		"data":    logs,
	})
}

// GetTaskLogFile 获取任务日志文件内容
func (h *TaskHandler) GetTaskLogFile(c *gin.Context) {
	taskID, err := strconv.ParseUint(c.Param("id"), 10, 64)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    400,
			"message": "无效的任务ID",
		})
		return
	}

	logID := c.Param("log_id")
	if logID == "" {
		// 获取最新的日志
		var log model.TaskLog
		if err := h.db.Where("task_id = ?", taskID).Order("id desc").First(&log).Error; err != nil {
			c.JSON(http.StatusNotFound, gin.H{
				"code":    404,
				"message": "日志不存在",
			})
			return
		}
		logID = strconv.FormatUint(uint64(log.ID), 10)
	}

	// TODO: 从文件系统读取日志内容
	c.JSON(http.StatusOK, gin.H{
		"code":    0,
		"message": "success",
		"data":    "日志内容",
	})
}

// readLastNLines 读取文件最后N行
func (h *TaskHandler) readLastNLines(filename string, n int) (string, error) {
	file, err := os.Open(filename)
	if err != nil {
		return "", err
	}
	defer file.Close()

	// 获取文件大小
	stat, err := file.Stat()
	if err != nil {
		return "", err
	}

	// 从文件末尾开始读取
	var lines []string
	var buffer []byte
	var position int64 = stat.Size()
	for len(lines) < n && position > 0 {
		// 每次读取4KB
		readSize := int64(4096)
		if position < readSize {
			readSize = position
		}
		position -= readSize

		buffer = make([]byte, readSize)
		_, err = file.ReadAt(buffer, position)
		if err != nil {
			return "", err
		}

		// 将缓冲区内容按行分割
		for i := len(buffer) - 1; i >= 0 && len(lines) < n; i-- {
			if buffer[i] == '\n' {
				lines = append(lines, string(buffer[i+1:]))
				buffer = buffer[:i]
			}
		}
	}

	// 反转行顺序
	for i := 0; i < len(lines)/2; i++ {
		lines[i], lines[len(lines)-1-i] = lines[len(lines)-1-i], lines[i]
	}

	return string(buffer) + "\n" + string(lines[0]), nil
}
